
/* verilator lint_off UNUSED */
//--xuezhen--

`include "defines.v"

module if_stage(
    input wire              clk,
    input wire              rst,

    input wire              stall_i,
    input wire              flush_i,

    input wire              transfer_flag_i,
    input wire [`REG_BUS]   transfer_address_i,

    input wire              exception_flag_i,
    input wire [`REG_BUS]   exception_addr_i,

    output wire [63 : 0]    inst_addr,
    output wire             inst_ena
    
);
    reg [`REG_BUS]pc;
    
    wire [`REG_BUS] pc_add_4;
    wire [`REG_BUS] pc_value;

    assign pc_add_4 = pc + 64'h4;
    assign pc_value = exception_flag_i  ? exception_addr_i   :
                      transfer_flag_i   ? transfer_address_i : pc_add_4;

    // fetch an instruction
    always@( posedge clk )
    begin
        if( rst == 1'b1 || flush_i == 1'b1)
        begin
            pc <= 64'h8000_0000;
        end
        else if(stall_i == 1'b1)
        begin
            pc <= pc;
        end
        else
        begin
            pc <= pc_value;
        end
    end

    assign inst_addr = pc;
    assign inst_ena  = ( rst == 1'b1 ) ? 0 : 1;
endmodule
